import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import plotly.express as px
import numpy as np
import plotly.io as pio
import plotly
df = pd.read_csv('formatted_data.csv')
df = df[df['fiscYear'].apply(lambda x : x >= 2014)]
df = df[['firstName', 'lastName', 'city', 'postalCode', 'entity', 'amount', 'fiscYear']]
dfMP = df[df['entity'].isin(['C.A.Q.- É.F.L.', 'P.C.Q./C.P.Q.','P.L.Q./Q.L.P.', 'P.Q.', 'Q.S.'])]
dfPCQ = df[df['entity'] == 'P.C.Q./C.P.Q.']
# Une personne unique s'identifie par son prenom, nom, ville et code postal
idPerson = ['firstName', 'lastName', 'city', 'postalCode']
#trouvons le parti pour lequel une personne a donnée le plus de fois dans une année et ce, pour chaque année
dfHistPivot = dfMP.pivot_table(index=idPerson, columns='fiscYear', values='entity',aggfunc=lambda x: x.mode().iat[0])
src = dfHistPivot.apply(lambda x : x.dropna().iloc[0], axis=1)
src.name = 'source'
dst = dfHistPivot.apply(lambda x : x.dropna().iloc[-1], axis=1)
dst.name = 'destination'
dfHistPivot['src'] = src
dfHistPivot['dst'] = dst
dfHistPivot['changed'] = src != dst
changedSeries = dfHistPivot[dfHistPivot['changed'] == True].groupby(['dst', 'src']).count()['changed']
changedSeries.name = 'nombre'
dfMP = df[df['entity'].isin(['C.A.Q.- É.F.L.', 'P.C.Q./C.P.Q.','P.L.Q./Q.L.P.', 'P.Q.', 'Q.S.'])]
dfPCQ = df[df['entity'] == 'P.C.Q./C.P.Q.']
sumDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc='sum')
nbrDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc='count')
meanDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc='mean')
modeDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc=pd.Series.mode)
pivotDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc=['count', 'sum', 'mean'])
Les données proviennent du site d'élection Québec. Elles ont été extraitent grâce à un code développer pour ce projet répertoire Github.
La source de données permet d'obtenir de l'information sur tous les donateurs depuis l'années 2000. Toutefois, nous avons accès au code postal et à la ville pour tous les donateurs depuis 2013 exclusivement. Pour cette raison, nous avons limité notre analyse de 2014 au 17 mars 2022. Une dernière mise à jour des données sera faite avant la publication.
Pour chaque dons, nous avons accès aux informations suivantes :
| firstName | lastName | amount | nbrPayment | entity | fiscYear | postalCode | city |
|---|---|---|---|---|---|---|---|
| Émilie | A Lachance | 100.0 | 1 | P.L.Q./Q.L.P. | 2016 | H2S2C5 | Montréal |
| Félix | A-Papineau | 100.0 | 1 | P.L.Q./Q.L.P. | 2015 | J0W1C0 | Ferme-neuve |
| Miriam | Aaron | 100.0 | 1 | P.L.Q./Q.L.P. | 2013 | H3G1L2 | Montréal |
| Miriam | Aaron | 50.0 | 1 | P.L.Q./Q.L.P. | 2014 | H3G1L2 | Montréal |
| ... | ... | ... | ... | ..... | ... | ... | ... |
dfHistPivot.shape[0]
120810
Il y a 120810 donateurs distincts entre 2014 et 2022
dst.value_counts()
P.Q. 38284 P.L.Q./Q.L.P. 29723 C.A.Q.- É.F.L. 24288 Q.S. 15817 P.C.Q./C.P.Q. 12698 Name: destination, dtype: int64
diff = dst.value_counts()-src.value_counts()
donateurs_distincts_PCQ = dst.value_counts().loc['P.C.Q./C.P.Q.']
donateurs_distincts_PCQ
12698
Le don le plus récent de 12698 donateurs distincts était pour le PCQ.
diff
P.Q. -894 P.L.Q./Q.L.P. -1699 C.A.Q.- É.F.L. 2224 Q.S. 39 P.C.Q./C.P.Q. 330 dtype: int64
autre_entite = diff.loc['P.C.Q./C.P.Q.']
autre_entite
330
De ces 12698 donateurs, seulement 330 donnaient précédemment pour un autre parti avant le PCQ
nouveau_donateur = dst.value_counts().loc['P.C.Q./C.P.Q.'] - diff.loc['P.C.Q./C.P.Q.']
pourc_nouveau = (donateurs_distincts_PCQ-autre_entite)/donateurs_distincts_PCQ *100
pourc_nouveau
97.40116553787999
97.4% des donateurs du PCQ n'ont jamais donnée pour d'autre parti entre 2014 et 2022
| firstName | lastName | city | postalCode | 2014.0 | 2015.0 | 2016.0 | 2017.0 | 2018.0 | 2019.0 | 2020.0 | 2021.0 | 2022.0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Alain | Beaulieu | Lefebvre | J0H 2C0 | P.C.Q./C.P.Q. | ||||||||
| Alain | Mattard | Montréal | H1R 3A3 | P.C.Q./C.P.Q. | P.C.Q./C.P.Q. | P.C.Q./C.P.Q. | ||||||
| Alain | Rochon | Cayamant | J0X 1Y0 | Q.S. | P.C.Q./C.P.Q. | P.C.Q./C.P.Q. | ||||||
| Alan | Wallis | Saint-denis-de-brompton | J0B 2P0 | C.A.Q.- É.F.L. | C.A.Q.- É.F.L. | C.A.Q.- É.F.L. | C.A.Q.- É.F.L. | C.A.Q.- É.F.L. | P.C.Q./C.P.Q. |
Dans cet exemple, les deux premiers donateurs seraient des nouveaux donateurs, car ils ont toujours donné pour le PCQ ou donné qu'une seule fois.
Les deux derniers seraient des donateurs qui ont changé d'allégence, car leur don le plus ancien est différent du plus récent.
plotly.offline.init_notebook_mode()
figPCQ = go.Figure(data=[go.Sankey(
node = dict(
pad = 15,
thickness = 20,
line = dict(color = "black", width = 0.5),
label = ["CAQ", "PCQ", "PLQ", "PQ", "QS"],
color = ["cyan", "purple", "red", "blue", "orange"]
),
link = dict(
source = [0,2,3,4], # indices correspond to labels, eg A1, A2, A1, B1, ...
target = [1,1,1,1],
value = changedSeries.values[4:8],
))])
figPCQ.update_layout(title_text="Changement d'allégence vers le PCQ", font_size=30)
figPCQ.show()
plotly.offline.init_notebook_mode()
px.bar(dfPCQ.groupby('city').sum()['amount'].sort_values(ascending=False)[:10].reset_index(),
y='city',
x='amount',
labels={'amount':'Somme de dons ($)',
'city':'Ville'},
title="Top 10 par somme de dons pour les villes du Québec")
plotly.offline.init_notebook_mode()
f2 = px.bar(nbrDonsYearMP.reset_index(),
x='fiscYear',
y='amount',
color='entity',
barmode='group',
title="Nombre de dons amassé par années pour chaque parti",
labels={'fiscYear':"Année Fiscale",
'amount' : "Nombre de dons"}
)
f2.show()
plotly.offline.init_notebook_mode()
f3 = px.bar(meanDonsYearMP.reset_index(),
x='fiscYear',
y='amount',
color='entity',
barmode='group',
title="Valeur moyenne de chaque dons effectué a un parti politique par année",
labels={'fiscYear':"Année Fiscale",
'amount' : "Valeur moyenne d'un don($)"}
)
f3.show()